#include "utils.h"

// #include "CertificateManager.h"
// #include "DDAP.pb.h"
// #include "Logging.h"
// #include "centralNode.h"
// #include "globalDefine.h"

#include <arpa/inet.h>
#include <asm-generic/errno-base.h>
#include <asm-generic/errno.h>
#include <asm-generic/socket.h>
#include <bits/types/struct_iovec.h>
#include <bits/types/struct_timeval.h>
#include <bits/types/struct_tm.h>
#include <cerrno>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <filesystem>
#include <fstream>
#include <ifaddrs.h>
#include <iostream>
#include <mutex>
#include <net/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/params.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/types.h>
#include <openssl/x509.h>
#include <random>
#include <signal.h>
#include <sstream>
#include <string>
#include <strings.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
namespace fs = std::filesystem;

namespace droneswarm
{

    void CondPanic( bool condition, std::string err )
    {
        // 只有条件为假时，才会进入断言。
        if ( !condition )
        {
            std::cout << "[assert by] (" << __FILE__ << ":" << __LINE__ << "),err: " << err << std::endl;
            // LOG << "[assert by] (" << __FILE__ << ":" << __LINE__ << "),err: " << err << '\n';
            assert( condition );
        }
    }
    ssize_t readn( int fd, void *buff, size_t n )
    {
        size_t nleft = n;
        ssize_t nread = 0;
        ssize_t readSum = 0;
        char *ptr = ( char * )buff;
        while ( nleft > 0 )
        {
            if ( ( nread = read( fd, ptr, nleft ) ) < 0 )
            {
                if ( errno == EINTR )
                    nread = 0;
                else if ( errno == EAGAIN )
                {
                    return readSum;
                }
                else
                {
                    return -1;
                }
            }
            else if ( nread == 0 )
                break;
            readSum += nread;
            nleft -= nread;
            ptr += nread;
        }
        return readSum;
    }
    ssize_t readn( int fd, std::string &inBuffer, bool &zero )
    {
        ssize_t nread = 0;
        ssize_t readSum = 0;
        while ( true )
        {

            unsigned char buff[ MAX_BUFF ];
            if ( ( nread = read( fd, buff, MAX_BUFF ) ) < 0 )
            {
                if ( errno == EINTR )
                    continue;
                else if ( errno == EAGAIN )
                {
                    return readSum;
                }
                else
                {
                    perror( "read error" );
                    return -1;
                }
            }
            else if ( nread == 0 )
            {
                // std::cout << "106" << std::endl;
                zero = true;
                break;
            }

            readSum += nread;
            // 需要将二进制字符串转换吧
            std::string tmpString( reinterpret_cast< const char * >( buff ), nread );
            inBuffer += tmpString;
            if ( nread < MAX_BUFF )
            {
                break;
            }
        }
        return readSum;
    }

    ssize_t readn( int fd, std::string &inBuffer )
    {
        ssize_t nread = 0;
        ssize_t readSum = 0;
        while ( true )
        {
            char buff[ MAX_BUFF ];
            if ( ( nread = read( fd, buff, MAX_BUFF ) ) < 0 )
            {
                if ( errno == EINTR )
                    continue;
                else if ( errno == EAGAIN )
                {
                    return readSum;
                }
                else
                {
                    perror( "read error" );
                    return -1;
                }
            }
            else if ( nread == 0 )
            {
                // printf("redsum = %d\n", readSum);
                break;
            }
            // printf("before inBuffer.size() = %d\n", inBuffer.size());
            // printf("nread = %d\n", nread);
            readSum += nread;
            // buff += nread;
            inBuffer += std::string( buff, buff + nread );
            // printf("after inBuffer.size() = %d\n", inBuffer.size());
        }
        return readSum;
    }

    ssize_t writen( int fd, void *buff, size_t n )
    {
        size_t nleft = n;
        ssize_t nwritten = 0;
        ssize_t writeSum = 0;
        char *ptr = ( char * )buff;
        while ( nleft > 0 )
        {
            if ( ( nwritten = write( fd, ptr, nleft ) ) <= 0 )
            {
                if ( nwritten < 0 )
                {
                    if ( errno == EINTR )
                    {
                        nwritten = 0;
                        continue;
                    }
                    else if ( errno == EAGAIN )
                    {
                        return writeSum;
                    }
                    else
                        return -1;
                }
            }
            writeSum += nwritten;
            nleft -= nwritten;
            ptr += nwritten;
        }
        return writeSum;
    }

    ssize_t writen( int fd, std::string &sbuff )
    {
        size_t nleft = sbuff.size();
        ssize_t nwritten = 0;
        ssize_t writeSum = 0;
        const char *ptr = sbuff.c_str();
        while ( nleft > 0 )
        {
            // std::cout << "写数据176" << std::endl;
            if ( ( nwritten = write( fd, ptr, nleft ) ) <= 0 )
            {
                if ( nwritten < 0 )
                {
                    if ( errno == EINTR )
                    {
                        nwritten = 0;
                        continue;
                    }
                    else if ( errno == EAGAIN )
                        break;
                    else
                        return -1;
                }
            }
            writeSum += nwritten;
            nleft -= nwritten;
            ptr += nwritten;
        }
        if ( writeSum == static_cast< int >( sbuff.size() ) )
            sbuff.clear();
        else
            sbuff = sbuff.substr( writeSum );
        return writeSum;
    }
    void shutDownWR( int fd )
    {
        shutdown( fd, SHUT_WR );
        // printf("shutdown\n");
    }

    std::string readFromFile( std::string path )
    {

        // 打开文件
        std::ifstream file;
        file.open( path, std::ios::in );
        CondPanic( file.is_open(), "File open is error" );
        // 创建字符流缓冲区
        std::stringstream ss;
        ss << file.rdbuf();
        std::string tmp;
        std::string buffer( ss.str() );
        // while ( std::getline( file, tmp ) )
        // {
        //     buffer = buffer + tmp + '\n';
        // }
        file.close();
        return buffer;
    }

    std::string DateFormat()
    {
        std::string weekdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
        std::string months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
        // 时间设置
        // 首先先获取时间，先要定义tm结构体
        struct timeval tv;
        gettimeofday( &tv, NULL );
        time_t time = tv.tv_sec;
        // 然后将time转换为tm结构体类型
        struct tm *now_time = localtime( &time );
        // int转换为字符串
        std::stringstream ss;
        // 将int类型写入到ss中
        /*
            std::setw 和 std::setfill 是 iostream 库中的两个格式化函数，用于控制输出的格式。
            std::setw(int n) 函数设置下一个输出项的最小字段宽度为 n 个字符
            std::setfill(char c) 函数设置用于填充额外空间的字符为 c。默认的填充字符是空格（' '），但可以通过
           std::setfill 更改
        */
        ss << "Date: " << weekdays[ now_time->tm_wday ] << ", " << now_time->tm_mday << " "
           << months[ now_time->tm_mon ] << " " << ( 1900 + now_time->tm_year ) << " " << std::setw( 2 )
           << std::setfill( '0' ) << now_time->tm_hour << ":" << std::setw( 2 ) << std::setfill( '0' )
           << now_time->tm_min << ":" << std::setw( 2 ) << std::setfill( '0' ) << now_time->tm_sec << " " << "GMT\r\n";
        // 将其转换为字符串
        std::string date = ss.str();
        return date;
    }
    std::string modifyFilePath( const std::string &fileName )
    {
        std::string tmp;
        // 如果前面有"/",则需要移除/
        // 使用 filePath = basePath / "systemLog" / filePath; 需要确保basePath第一个字符不是/
        //
        if ( !fileName.empty() && fileName[ 0 ] == '/' )
        {
            tmp = fileName.substr( 1 );
        }
        else
        {
            tmp = fileName;
        }
        // 然后检查后面是不是跟的..
        size_t pos = tmp.find( "../" );
        if ( pos != std::string::npos )
        {
            // 说明后面跟的..则要清除掉..
            tmp = tmp.substr( pos + 2 );
        }

        fs::path basePath = "/home/sally/桌面/DroneSystem";
        fs::path filePath = tmp;
        // 标准化输入文件路径,这个只能检查比较深度的..
        filePath = filePath.lexically_normal();

        // 转换文件路径为小写以进行不区分大小写的后缀匹配
        std::string lower_case_path = filePath.string();
        std::transform( lower_case_path.begin(), lower_case_path.end(), lower_case_path.begin(), []( unsigned char c ) {
            return std::tolower( c );
        } );

        // 构建最终路径
        if ( filePath.string().find( ".html" ) != std::string::npos )
        {
            filePath = basePath / "html" / filePath;
        }
        else if ( filePath.string().find( ".log" ) != std::string::npos )
        {

            filePath = basePath / "systemLog" / filePath;
        }
        else if ( filePath.string().find( ".txt" ) != std::string::npos )
        {
            filePath = basePath / "docs" / filePath;
        }
        else
        {
            fs::path error = "/Error.html";
            filePath = basePath / "Error" / error;
        }
        // 安全检查：确保最终路径位于基路径之下
        if ( filePath.lexically_normal().string().rfind( basePath.string(), 0 ) == 0 )
        {
            if ( fs::exists( filePath ) )
            {

                return filePath.string();
            }
            else
            {
                return basePath.string() + "/Error/NotFound.html";
            }
        }
        else
        {
            // LOG << "Invalid path detected: " << filePath.string() << "\n";

            return "/home/sally/桌面/DroneSystem/Error/Error.html";
        }
    }
    int socket_bind_listen( int port )
    {
        // 检查port取值是否正确
        if ( port < 0 || port > 65535 )
        {
            return -1;
        }

        // 创建socekt，返回监听描述符
        int listen_fd = 0;
        listen_fd = socket( AF_INET, SOCK_STREAM, 0 );
        if ( listen_fd == -1 )
        {
            return -1;
        }
        /*
            setsockopt 函数调用用于设置 SO_REUSEADDR
           选项，使得服务器程序能够在不常规的关闭后快速重启，并重新绑定到其端口，而不需要等待操作系统释放端口
        */
        int optval = 1;
        if ( ( setsockopt( listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof( optval ) ) == -1 ) )
        {
            close( listen_fd );
            return -1;
        }

        // 将监听描述符和服务器ip和端口绑定
        struct sockaddr_in server_addr;
        bzero( ( char * )&server_addr, sizeof( server_addr ) );
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl( INADDR_ANY );
        server_addr.sin_port = htons( ( unsigned short )port );
        if ( bind( listen_fd, ( struct sockaddr * )&server_addr, sizeof( server_addr ) ) == -1 )
        {
            close( listen_fd );
            return -1;
        }

        // 设置最大监听数量
        if ( listen( listen_fd, 2048 ) == -1 )
        {
            close( listen_fd );
            return -1;
        }
        if ( listen_fd == -1 )
        {
            close( listen_fd );
            return -1;
            ;
        }
        return listen_fd;
    }

    /*
    这个函数 handle_for_sigpipe() 用于处理在 UNIX 和类 UNIX 系统中可能发生的 SIGPIPE 信号。SIGPIPE
    信号通常在进程向一个没有读端的管道（pipe）或者已经关闭的 socket
    写入数据时产生。如果不处理这个信号，进程会被默认终止。因此，这个函数的主要目的是配置系统忽略 SIGPIPE
    信号，从而防止程序因意外的 SIGPIPE 而退出。
    */
    void handle_for_sigpipe()
    {
        struct sigaction sa;
        memset( &sa, '\0', sizeof( sa ) );
        sa.sa_handler = SIG_IGN;
        sa.sa_flags = 0;
        if ( sigaction( SIGPIPE, &sa, NULL ) )
            return;
    }

    int setSocketNonBlocking( int fd )
    {
        // 获取当前的文件描述符状态：
        int flag = fcntl( fd, F_GETFL, 0 );
        if ( flag == -1 )
            return -1;

        flag |= O_NONBLOCK;
        // F_SETFL 命令来设置文件描述符的状态标志。
        if ( fcntl( fd, F_SETFL, flag ) == -1 )
            return -1;
        return 0;
    }

    void setSocketNodelay( int fd )
    {
        int enable = 1;
        setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, ( void * )&enable, sizeof( enable ) );
    }

    // SSL_CTX *initializeSSL()
    // {
    //     //初始化OpenSSL库
    //     SSL_load_error_strings();      //加载所有错误消息字符串。
    //     SSL_library_init();            //初始化Openssl的加密算法库。
    //     OpenSSL_add_ssl_algorithms();  //注册Openssl库中所有的加密算法。

    //     //创建SSL上下文
    //     SSL_CTX *ctx = SSL_CTX_new( TLS_server_method() );
    //     if ( ctx == NULL )
    //     {
    //         ERR_print_errors_fp( stderr );
    //         exit( EXIT_FAILURE );
    //     }
    //     //加载公钥证书
    //     SSL_CTX_use_certificate_file( ctx, "/path", SSL_FILETYPE_PEM );
    //     //加载私钥
    //     SSL_CTX_use_PrivateKey_file( ctx, "/path", SSL_FILETYPE_PEM );

    //     //检查私钥和证书的匹配性
    //     if ( !SSL_CTX_check_private_key( ctx ) )
    //     {
    //         fprintf( stderr, "Private key does not match the public certificate\n" );
    //         LOG << "Private key does not match the public certificate\n";
    //         exit( EXIT_FAILURE );
    //     }
    //     return ctx;
    // }

    uint64_t getTime()
    {

        struct timeval ts;
        if ( gettimeofday( &ts, NULL ) == 0 )
        {
            uint64_t timestamp = ( uint64_t )ts.tv_sec * 1000000 + ( uint64_t )ts.tv_usec;
            return timestamp;
        }
        else
        {
            return 0;
        }
    }
    std::string sha256_check( const unsigned char *data, size_t length )
    {
        // unsigned char hash[SHA256_DIGEST_LENGTH];
        // SHA256_CTX;
        // 使用EVP 接口来使用SHA_256哈希计算
        EVP_MD_CTX *ctx = EVP_MD_CTX_new();
        if ( ctx == nullptr )
        {
            // LOG << "Failed to create EVP_MD_CTX in sha256_check" << '\n';
            return "";
        }

        // 使用EVP_SHA256()获取SHA-256摘要算法
        if ( EVP_DigestInit_ex( ctx, EVP_sha256(), nullptr ) != 1 )
        {
            // LOG << "EVP_DigestInit_ex failed in sha256_check" << '\n';
            EVP_MD_CTX_free( ctx );
            return "";
        }

        // 传入数据
        if ( EVP_DigestUpdate( ctx, data, length ) != 1 )
        {
            // LOG << "EVP_DigestUpdate failed in sha256_check" << '\n';
            EVP_MD_CTX_free( ctx );
            return "";
        }

        // 获取哈希结果
        unsigned char *hash = ( unsigned char * )OPENSSL_malloc( SHA256_DIGEST_LENGTH );
        if ( !hash )
        {
            // LOG << "OPENSSL_malloc failed in sha256_check" << '\n';
            EVP_MD_CTX_free( ctx );
            return "";
        }
        unsigned int hash_len = 0;
        if ( EVP_DigestFinal_ex( ctx, hash, &hash_len ) != 1 )
        {
            std::cerr << "EVP_DigestFinal_ex failed" << std::endl;
            OPENSSL_free( hash );
            EVP_MD_CTX_free( ctx );
            return "";
        }

        // std::cout << "520 check: " << hash_len << std::endl;
        char hash_c[ SHA256_DIGEST_LENGTH ];
        memcpy( hash_c, hash, SHA256_DIGEST_LENGTH );
        std::string hash_str( hash_c, SHA256_DIGEST_LENGTH );
        OPENSSL_free( hash );
        EVP_MD_CTX_free( ctx );
        return hash_str;
    }

    bool readAndDeserialize( SigningMessage &signMessage,
                             int fd,
                             char *receiveBuff,
                             char *tmpBuffer,
                             size_t receiveBuff_length,
                             size_t tmpBuffer_length,
                             int timeout )
    {
        TimePoint now = std::chrono::steady_clock::now();
        TimePoint expiredTime = now + std::chrono::milliseconds( timeout );
        ssize_t bytesRead = 0;
        ssize_t totalBytesRead = 0;
        while ( std::chrono::steady_clock::now() < expiredTime )
        {

            bytesRead = read( fd, receiveBuff, receiveBuff_length );
            if ( bytesRead < 0 )
            {
                if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    continue;
                }
            }
            else if ( bytesRead == 0 )
            {
                std::cerr << "连接" << fd << "已关闭" << std::endl;
                close( fd );
                return false;
            }
            // 先将一部分数据转换反序列化为消息行
            //  buffer.insert( buffer.end(), receiveBuff, receiveBuff + bytesRead );

            // 复制数据到临时缓冲区
            if ( totalBytesRead + bytesRead > 2048 )
            {
                std::cerr << "缓冲区溢出，断开连接" << std::endl;
                close( fd );
                return false;
            }

            memcpy( tmpBuffer + totalBytesRead, receiveBuff, bytesRead );
            totalBytesRead += bytesRead;
            memset( receiveBuff, 0, receiveBuff_length );

            if ( ( size_t )totalBytesRead > tmpBuffer_length )
            {
                std::cerr << "数据大小超出缓冲区，请增加缓冲区容量" << std::endl;
                return false;
            }

            // 需要
            //  memset( receiveBuff, 0, 2048 );

            // 如果数据还没有到达，就会导致数据反序列化失败，那么就继续读，但是次数不能超过十次。

            if ( !signMessage.ParseFromArray( tmpBuffer, totalBytesRead ) )
            {

                continue;
            }
            else
            {
                // std::cout << "hmaMessage数据反序列化成功" << std::endl;
                return true;
            }
        }
        return false;
    }

    bool readAndDeserialize( FullMessage &message,
                             int fd,
                             char *receiveBuff,
                             char *tmpBuffer,
                             size_t receiveBuff_length,
                             size_t tmpBuffer_length,
                             int timeout )
    {

        TimePoint now = std::chrono::steady_clock::now();
        TimePoint expiredTime = now + std::chrono::milliseconds( timeout );
        ssize_t bytesRead = 0;
        ssize_t totalBytesRead = 0;
        while ( std::chrono::steady_clock::now() < expiredTime )
        {

            bytesRead = read( fd, receiveBuff, receiveBuff_length );
            if ( bytesRead < 0 )
            {
                if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    continue;
                }
            }
            else if ( bytesRead == 0 )
            {
                std::cerr << "连接" << fd << "已关闭" << std::endl;
                close( fd );
                return false;
            }
            // 先将一部分数据转换反序列化为消息行
            //  buffer.insert( buffer.end(), receiveBuff, receiveBuff + bytesRead );

            // 复制数据到临时缓冲区
            if ( totalBytesRead + bytesRead > 2048 )
            {
                std::cerr << "缓冲区溢出，断开连接" << std::endl;
                close( fd );
                return false;
            }

            memcpy( tmpBuffer + totalBytesRead, receiveBuff, bytesRead );
            totalBytesRead += bytesRead;
            memset( receiveBuff, 0, receiveBuff_length );

            if ( ( size_t )totalBytesRead > tmpBuffer_length )
            {
                std::cerr << "数据大小超出缓冲区，请增加缓冲区容量" << std::endl;
                return false;
            }

            // 需要
            //  memset( receiveBuff, 0, 2048 );

            // 如果数据还没有到达，就会导致数据反序列化失败，那么就继续读，但是次数不能超过十次。

            if ( !message.ParseFromArray( tmpBuffer, totalBytesRead ) )
            {

                continue;
            }
            else
            {
                // std::cout << "hmaMessage数据反序列化成功" << std::endl;
                return true;
            }
        }
        return false;
        // return true;
    }

    bool readAndDeserialize( needHMACMessage &hmaMessage,
                             int fd,
                             char *receiveBuff,
                             char *tmpBuffer,
                             size_t receiveBuff_length,
                             size_t tmpBuffer_length,
                             int timeout )
    {
        TimePoint now = std::chrono::steady_clock::now();
        TimePoint expiredTime = now + std::chrono::milliseconds( timeout );
        ssize_t bytesRead = 0;
        ssize_t totalBytesRead = 0;
        while ( std::chrono::steady_clock::now() < expiredTime )
        {

            bytesRead = read( fd, receiveBuff, receiveBuff_length );
            if ( bytesRead < 0 )
            {
                if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    continue;
                }
            }
            else if ( bytesRead == 0 )
            {
                std::cerr << "连接" << fd << "已关闭" << std::endl;
                close( fd );
                return false;
            }
            // 先将一部分数据转换反序列化为消息行
            //  buffer.insert( buffer.end(), receiveBuff, receiveBuff + bytesRead );

            // 复制数据到临时缓冲区
            if ( totalBytesRead + bytesRead > 2048 )
            {
                std::cerr << "缓冲区溢出，断开连接" << std::endl;
                close( fd );
                return false;
            }

            memcpy( tmpBuffer + totalBytesRead, receiveBuff, bytesRead );
            totalBytesRead += bytesRead;
            memset( receiveBuff, 0, receiveBuff_length );

            if ( ( size_t )totalBytesRead > tmpBuffer_length )
            {
                std::cerr << "数据大小超出缓冲区，请增加缓冲区容量" << std::endl;
                return false;
            }

            // 需要
            //  memset( receiveBuff, 0, 2048 );

            // 如果数据还没有到达，就会导致数据反序列化失败，那么就继续读，但是次数不能超过十次。

            if ( !hmaMessage.ParseFromArray( tmpBuffer, totalBytesRead ) )
            {

                continue;
            }
            else
            {
                // std::cout << "hmaMessage数据反序列化成功" << std::endl;
                return true;
            }
        }
        return false;
    }

    bool parseMessage( FullMessage &message,
                       int accept_fd,
                       MessageType &mt,
                       std::string &version,
                       uint32_t &sourceAddress,
                       uint32_t &destinationAddress,
                       std::string &messageID,
                       bool &needAck,
                       bool &fragment,
                       bool &is_Encry,
                       CompressionType &cpt,
                       EncryptionType &enct,
                       char *data_c,
                       size_t &dataSize )
    {

        const MessageLine &messageLine = message.messageline();
        mt = messageLine.messagetype();
        // 首先必须要发送认证请求消息

        version = messageLine.version();

        // 获取消息行字段标记的长度

        // 获取消息头
        const MessageHeader &messageHeader = message.messageheader();
        messageID = messageHeader.messageid();
        sourceAddress = messageHeader.sourceaddress();
        destinationAddress = messageHeader.destinationaddress();

        uint64_t timeStamp = messageHeader.timestamp();
        std::string checkNum = messageHeader.checksum();

        for ( int i = 0; i < messageHeader.flags_size(); ++i )
        {
            if ( messageHeader.flags( i ) == FLAG_NEEDS_ACK )
            {
                needAck = true;
            }
            else if ( messageHeader.flags( i ) == FLAG_LAST_FRAGMENT )
            {
                fragment = true;
            }
            else if ( messageHeader.flags( i ) == FLAG_ENCRYPTED )
            {
                is_Encry = true;
            }
            else
            {
                std::cerr << "Wrong flag" << std::endl;
                return false;
            }
        }

        ContentType ct = messageHeader.contenttype();
        if ( ct != CONTENT_TEXT )
        {
            // 那么就是DER证书
            std::cerr << "无法处理DER证书！" << '\n';
            return false;
        }

        cpt = messageHeader.compression();

        enct = messageHeader.encryption();

        // 判断头部长度加消息体长度加消息行是否等于接收数据的长度

        // 因为认证消息是公开的，不需要加密，因为不包含敏感信息。加密了的话，服务器端还没有协商密钥就无法解密了
        if ( is_Encry == false && enct == ENC_NONE )
        {
            std::cout << "当前信息没有采取任何加密方式，以明文形式传递" << std::endl;
        }
        else if ( is_Encry == false && enct == ENC_AES )
        {
            std::cerr << accept_fd << "发送的报文加密标识为和加密方式不一致，认证失败连接关闭" << '\n';
            return false;
        }
        else if ( is_Encry == true && enct == ENC_NONE )
        {
            std::cerr << accept_fd << "发送的报文加密标识为和加密方式不一致，认证失败连接关闭" << '\n';
            return false;
        }
        else
        {
            std::cerr << "无法解密通信端：" << accept_fd << "发送的加密数据" << '\n';
            return false;
        }

        // 检查时间戳
        // 获取当前的时间戳
        uint64_t nowtime = getTime();
        if ( nowtime - timeStamp > 60000000 )
        {
            // 视为重放攻击，拒绝认证，返回
            std::cerr << "该连接" << accept_fd << "发送的报文时间戳超时，可能为重放攻击" << '\n';
            return false;
        }

        // 获取原始数据的大小
        uint32_t receiveDataLen = messageHeader.datalength();

        // 消息体
        const MessageBody &body = message.messagebody();
        const std::string &data = body.data();

        // 发送方是对原始数据进行校验，因此我们也需要对原始数据进行校验
        std::string check = sha256_check( ( const unsigned char * )data.c_str(), receiveDataLen );
        if ( check != checkNum )
        {
            std::cerr << "该连接" << accept_fd << "发送报文的校验和不同，可能已被篡改" << '\n';
            return false;
        }
        dataSize = data.size();
        memcpy( data_c, data.c_str(), dataSize );
        // std::cout << "数据分析通过" << std::endl;
        return true;
    }

    bool parseMessage( FullMessage &message, messageInfo &minfo, int fd )
    {
        const MessageLine &messageLine = message.messageline();
        minfo.mt = messageLine.messagetype();
        // 首先必须要发送认证请求消息

        minfo.version = messageLine.version();

        // 获取消息行字段标记的长度

        // 获取消息头
        const MessageHeader &messageHeader = message.messageheader();
        minfo.messageID = messageHeader.messageid();
        minfo.sourceAddress = messageHeader.sourceaddress();
        minfo.destinationAddress = messageHeader.destinationaddress();

        uint64_t timeStamp = messageHeader.timestamp();
        std::string checkNum = messageHeader.checksum();
        minfo.dataType = messageHeader.requestdatatype();
        minfo.needAck = false;
        minfo.fragment = false;
        minfo.is_Encry = false;

        for ( int i = 0; i < messageHeader.flags_size(); ++i )
        {
            if ( messageHeader.flags( i ) == FLAG_NEEDS_ACK )
            {
                minfo.needAck = true;
            }
            else if ( messageHeader.flags( i ) == FLAG_LAST_FRAGMENT )
            {
                minfo.fragment = true;
            }
            else if ( messageHeader.flags( i ) == FLAG_ENCRYPTED )
            {
                minfo.is_Encry = true;
            }
            else
            {
                std::cerr << "Wrong flag" << std::endl;
                return false;
            }
        }

        ContentType ct = messageHeader.contenttype();
        if ( ct != CONTENT_TEXT )
        {
            // 那么就是DER证书
            std::cerr << "无法处理DER证书！" << '\n';
            return false;
        }

        minfo.cpt = messageHeader.compression();

        minfo.enct = messageHeader.encryption();

        // 判断头部长度加消息体长度加消息行是否等于接收数据的长度

        // 因为认证消息是公开的，不需要加密，因为不包含敏感信息。加密了的话，服务器端还没有协商密钥就无法解密了
        if ( minfo.is_Encry == false && minfo.enct == ENC_NONE )
        {
            // std::cout << "当前消息未经加密，按照明文方式发送" << std::endl;
        }
        else if ( minfo.is_Encry == false && minfo.enct == ENC_AES )
        {
            std::cerr << fd << "发送的报文加密标识为和加密方式不一致，认证失败连接关闭" << '\n';
            return false;
        }
        else if ( minfo.is_Encry == true && minfo.enct == ENC_NONE )
        {
            std::cerr << fd << "发送的报文加密标识为和加密方式不一致，认证失败连接关闭" << '\n';
            return false;
        }
        else if ( minfo.is_Encry == true && minfo.enct == ENC_AES )
        {
            // std::cout << "数据通过加密方式发送" << std::endl;
        }
        else
        {
            std::cerr << "无法解密通信端：" << fd << "发送的加密数据" << '\n';
            return false;
        }

        // 检查时间戳
        // 获取当前的时间戳
        uint64_t nowtime = getTime();
        if ( nowtime - timeStamp > 60000000 )
        {
            // 视为重放攻击，拒绝认证，返回
            std::cerr << "该连接" << fd << "发送的报文时间戳超时，可能为重放攻击" << '\n';
            return false;
        }

        // 获取原始数据的大小
        uint32_t receiveDataLen = messageHeader.datalength();

        // 消息体
        const MessageBody &body = message.messagebody();
        const std::string &data = body.data();

        // 发送方是对原始数据进行校验，因此我们也需要对原始数据进行校验
        std::string check = sha256_check( ( const unsigned char * )data.c_str(), receiveDataLen );
        if ( check != checkNum )
        {
            std::cerr << "该连接" << fd << "发送报文的校验和不同，可能已被篡改" << '\n';
            return false;
        }

        minfo.realData = data;
        minfo.realDataLength = data.size();
        // std::cout << "数据分析通过" << std::endl;
        return true;
    }

    std::string constructMessage( std::string sourceData,
                                  uint32_t sourceDataLength,
                                  MessageType mt,
                                  std::string version,
                                  uint32_t sourceAddress,
                                  uint32_t destinationAddress,
                                  bool needAck,
                                  bool fragmet,
                                  bool is_Encry,
                                  CompressionType cpt,
                                  EncryptionType enct )
    {
        // 构造报文
        FullMessage message;
        MessageLine *ml = message.mutable_messageline();

        switch ( mt )
        {
        case AUTH_REQUEST:
        case AUTH_RESPONSE:
        case AUTH_ACKNOWLEDGEMENT:
        case DATA_SUBMISSION:
        case DATA_REQUEST:
        case DATA_ACKNOWLEDGEMENT:
        case NOTIFICATION:
        case CONTROL_MESSAGE:
        case STATUS_QUERY:
            ml->set_messagetype( mt );
            break;

        default:
            // 可以打印错误日志或者处理错误
            std::cerr << "Invalid message type: " << mt << std::endl;
            return "";  // 或者返回合适的错误值
        }

        if ( version == "V1" )
        {
            ml->set_version( "V1" );
        }

        MessageHeader *mh = message.mutable_messageheader();
        BIGNUM *mID = generate_large_serial_number();
        char *MessageID_c = BN_bn2hex( mID );
        if ( MessageID_c == NULL )
        {
            std::cerr << "Error converting BIGNUM to hex" << std::endl;
            BN_free( mID );
            return "";
        }
        std::string MessageID_str( MessageID_c );

        mh->set_messageid( MessageID_str );
        BN_free( mID );

        uint64_t nowtime = getTime();
        mh->set_timestamp( nowtime );

        if ( sourceAddress == 0 && destinationAddress == 0 )
        {
            // 说明用户为了保护隐私而因此了ip地址，因此我们也因此
            mh->set_sourceaddress( 0 );
            mh->set_destinationaddress( 0 );
        }
        else if ( sourceAddress != 0 && destinationAddress != 0 )
        {
            mh->set_sourceaddress( destinationAddress );
            mh->set_destinationaddress( sourceAddress );
        }
        else
        {
            std::cerr << "源地址和目的地址错误" << std::endl;
            return "";
        }
        if ( needAck )
        {
            mh->add_flags( FLAG_NEEDS_ACK );
        }
        if ( fragmet )
        {
            mh->add_flags( FLAG_LAST_FRAGMENT );
        }
        if ( is_Encry )
        {
            mh->add_flags( FLAG_ENCRYPTED );
            mh->set_encryption( enct );
        }

        mh->set_contenttype( CONTENT_TEXT );

        if ( cpt == COMP_NONE )
        {
            mh->set_compression( COMP_NONE );
        }
        else if ( cpt == COMP_GZIP )
        {
            mh->set_compression( COMP_GZIP );
        }

        mh->set_datalength( sourceDataLength );

        // 校验位
        std::string check = sha256_check( ( const unsigned char * )sourceData.c_str(), sourceDataLength );
        if ( check.empty() )
        {
            std::cerr << "生成校验码失败" << std::endl;
            return "";
        }
        mh->set_checksum( check );

        MessageBody *mb = message.mutable_messagebody();
        mb->set_data( sourceData );

        // 序列化数据
        std::string SeString;
        if ( !message.SerializePartialToString( &SeString ) )
        {
            std::cerr << "Failed to serialize message." << std::endl;
            // LOG << "Failed to serialize message." << '\n';
            return "";
        }
        return SeString;
    }
    std::string constructMessage( FullMessage &message, messageInfo &messInfo )
    {
        // 构造报文
        MessageLine *ml = message.mutable_messageline();
        MessageType mt = messInfo.mt;
        switch ( mt )
        {
        case AUTH_REQUEST:
        case AUTH_RESPONSE:
        case AUTH_ACKNOWLEDGEMENT:
        case AUTH_FINAL_ACKNOWLEDGEMENT:
        case DATA_REQUEST:
        case DATA_RESPONSE:
        case DATA_SUBMISSION:
        case DATA_ACKNOWLEDGEMENT:
        case NOTIFICATION:
        case CONTROL_MESSAGE:
        case STATUS_QUERY:
            ml->set_messagetype( mt );
            break;

        default:
            // 可以打印错误日志或者处理错误
            std::cerr << "Invalid message type: " << mt << std::endl;
            return "";  // 或者返回合适的错误值
        }

        if ( messInfo.version == "V1" )
        {
            ml->set_version( "V1" );
        }

        MessageHeader *mh = message.mutable_messageheader();

        mh->set_messageid( messInfo.messageID );

        uint64_t nowtime = getTime();
        mh->set_timestamp( nowtime );

        if ( messInfo.sourceAddress == 0 && messInfo.destinationAddress == 0 )
        {
            // 说明用户为了保护隐私而因此了ip地址，因此我们也因此
            mh->set_sourceaddress( 0 );
            mh->set_destinationaddress( 0 );
        }
        else if ( messInfo.sourceAddress != 0 && messInfo.destinationAddress != 0 )
        {
            mh->set_sourceaddress( messInfo.destinationAddress );
            mh->set_destinationaddress( messInfo.sourceAddress );
        }
        else
        {
            std::cerr << "源地址和目的地址错误" << std::endl;
            return "";
        }
        if ( messInfo.needAck )
        {
            mh->add_flags( FLAG_NEEDS_ACK );
        }
        if ( messInfo.fragment )
        {
            mh->add_flags( FLAG_LAST_FRAGMENT );
        }
        if ( messInfo.is_Encry )
        {
            mh->add_flags( FLAG_ENCRYPTED );
            mh->set_encryption( messInfo.enct );
        }

        mh->set_contenttype( CONTENT_TEXT );

        if ( messInfo.cpt == COMP_NONE )
        {
            mh->set_compression( COMP_NONE );
        }
        else if ( messInfo.cpt == COMP_GZIP )
        {
            mh->set_compression( COMP_GZIP );
        }

        if ( messInfo.dataType != NOTBOTH )
        {
            mh->set_requestdatatype( messInfo.dataType );
        }
        mh->set_datalength( messInfo.realDataLength );

        // 校验位
        std::string check = sha256_check( ( const unsigned char * )messInfo.realData.c_str(), messInfo.realDataLength );
        if ( check.empty() )
        {
            std::cerr << "生成校验码失败" << std::endl;
            return "";
        }
        mh->set_checksum( check );

        MessageBody *mb = message.mutable_messagebody();
        mb->set_data( messInfo.realData );

        // 前面是构造消息对象，用于后续的序列化成字符串

        // 序列化数据
        std::string SeString;
        if ( !message.SerializePartialToString( &SeString ) )
        {
            std::cerr << "Failed to serialize message." << std::endl;
            // LOG << "Failed to serialize message." << '\n';
            return "";
        }
        return SeString;
    }

    // 获取本地的IPv4地址列表
    std::vector< std::string > getLocalIPv4Addresses()
    {
        std::vector< std::string > ipAddresses;
        struct ifaddrs *ifaddr, *ifa;

        if ( getifaddrs( &ifaddr ) == -1 )
        {
            perror( "getifaddrs" );
            return ipAddresses;
        }

        for ( ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next )
        {
            if ( ifa->ifa_addr == nullptr )
                continue;

            if ( ifa->ifa_addr->sa_family == AF_INET )
            {
                char ipStr[ INET_ADDRSTRLEN ];
                void *addr = &( ( struct sockaddr_in * )ifa->ifa_addr )->sin_addr;
                inet_ntop( AF_INET, addr, ipStr, sizeof( ipStr ) );
                ipAddresses.push_back( ipStr );
            }
        }

        freeifaddrs( ifaddr );
        return ipAddresses;
    }

    // 将IPv4字符串转换为uint32_t类型
    uint32_t ipv4StringToUint32( const std::string &ipv4Str )
    {
        struct in_addr ipv4Addr;
        if ( inet_pton( AF_INET, ipv4Str.c_str(), &ipv4Addr ) != 1 )
        {
            std::cerr << "Invalid IPv4 address: " << ipv4Str << std::endl;
            return 0;
        }
        return ntohl( ipv4Addr.s_addr );
    }

    // 将uint32_t格式的IPv4地址转换回字符串
    std::string uint32ToIpv4String( uint32_t ipv4Uint32 )
    {
        struct in_addr ipv4Addr;
        ipv4Addr.s_addr = htonl( ipv4Uint32 );
        char ipStr[ INET_ADDRSTRLEN ];
        if ( inet_ntop( AF_INET, &ipv4Addr, ipStr, INET_ADDRSTRLEN ) == nullptr )
        {
            std::cerr << "Failed to convert uint32 to IPv4 address" << std::endl;
            return "";
        }
        return std::string( ipStr );
    }

    void setMessageInfo( struct messageInfo &mi, MessageType mt )
    {
        mi.mt = mt;

        BIGNUM *mID = generate_large_serial_number();
        char *MessageID_c = BN_bn2hex( mID );
        if ( MessageID_c == NULL )
        {
            std::cerr << "Error converting BIGNUM to hex" << std::endl;
            BN_free( mID );
            return;
        }
        std::string MessageID_str( MessageID_c );
        mi.messageID = MessageID_str;
        BN_free( mID );
        OPENSSL_free( MessageID_c );
        if ( mt == AUTH_REQUEST )
        {
            mi.sourceAddress = 0;
            mi.destinationAddress = 0;
            mi.version = "V1";
            mi.needAck = false;
            mi.fragment = false;
            mi.is_Encry = false;
            mi.cpt = COMP_NONE;
            mi.enct = ENC_NONE;
        }
        else if ( mt == AUTH_FINAL_ACKNOWLEDGEMENT || mt == DATA_REQUEST || mt == DATA_ACKNOWLEDGEMENT
                  || mt == NOTIFICATION || mt == STATUS_QUERY )
        {
            mi.sourceAddress = ipv4StringToUint32( "127.0.0.1" );
            mi.destinationAddress = ipv4StringToUint32( "127.0.0.1" );
            mi.version = "V1";
            mi.needAck = false;
            mi.fragment = false;
            mi.is_Encry = true;
            mi.cpt = COMP_NONE;
            mi.enct = ENC_AES;
        }
        else if ( mt == AUTH_ACKNOWLEDGEMENT || mt == AUTH_RESPONSE )
        {
            mi.sourceAddress = 0;
            mi.destinationAddress = 0;
            mi.version = "V1";
            mi.needAck = true;
            mi.fragment = false;
            mi.is_Encry = false;
            mi.cpt = COMP_NONE;
            mi.enct = ENC_NONE;
        }
        else if ( mt == DATA_RESPONSE || mt == CONTROL_MESSAGE )
        {
            mi.sourceAddress = ipv4StringToUint32( "127.0.0.1" );
            mi.destinationAddress = ipv4StringToUint32( "127.0.0.1" );
            mi.version = "V1";
            mi.needAck = true;
            mi.fragment = false;
            mi.is_Encry = true;
            mi.cpt = COMP_NONE;
            mi.enct = ENC_AES;
        }
        else if ( mt == DATA_SUBMISSION )
        {
            mi.sourceAddress = ipv4StringToUint32( "127.0.0.1" );
            mi.destinationAddress = ipv4StringToUint32( "127.0.0.1" );
            mi.version = "V1";
            mi.needAck = true;
            mi.fragment = false;
            mi.is_Encry = true;
            mi.cpt = COMP_NONE;
            mi.enct = ENC_AES;
        }
        else
        {
            std::cerr << "错误: 提供了不支持的消息类型" << std::endl;
            return;
        }
    }

    void setDataTypeMessageInfo( struct messageInfo &mi, DataType dataType ) { mi.dataType = dataType; }

    bool generateHmac( const unsigned char *data,
                       size_t data_len,
                       const unsigned char *key,
                       size_t key_len,
                       unsigned char **hmac_value,
                       size_t *outlen )
    {
        // 创建并初始化HMAC上下文
        EVP_MAC_CTX *ctx = NULL;
        EVP_MAC *mac = NULL;

        OSSL_PARAM params[ 2 ];  // 这个参数是要用于EVP_MAC_init函数的参数
        // EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,const char *properties);

        mac = EVP_MAC_fetch( NULL, "HMAC", NULL );
        if ( !mac )
        {
            std::cerr << "EVP_MAC_fetch函数初始化mac失败" << std::endl;
            return false;
        }
        ctx = EVP_MAC_CTX_new( mac );
        if ( !ctx )
        {
            std::cerr << "使用mac来初始化ctx失败" << std::endl;
            EVP_MAC_free( mac );
            return false;
        }

        // 创建参数来告诉 OpenSSL 使用 SHA256 作为 HMAC 的底层散列函数。
        char digest[] = "SHA256";
        params[ 0 ] = OSSL_PARAM_construct_utf8_string( "digest", digest, 0 );
        params[ 1 ] = OSSL_PARAM_construct_end();

        /*
            初始化HAMC上下文：这是告诉OPENSSL的上下文ctx，使用哪种算法来作为HAMC的底层散列函数，并将密钥数据和密钥长度放入到MAC上下文中
            函数原型：
            int EVP_MAC_init(EVP_MAC_CTX *ctx, const unsigned char *key, size_t keylen,
                 const OSSL_PARAM params[]);
            返回值：成功返回1，失败返回0
        */
        if ( EVP_MAC_init( ctx, key, key_len, params ) != 1 )
        {
            std::cerr << "EVP_MAC_init 初始化MAC上下文失败" << std::endl;
            EVP_MAC_CTX_free( ctx );
            EVP_MAC_free( mac );
            return false;
        }

        /*
            更新数据到HMAC上下文，用于将原始数据和数据长度放入到HMAC的上下文中。
            函数原型：
            int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen);
            返回值：成功返回1，失败返回0
        */
        if ( EVP_MAC_update( ctx, data, data_len ) != 1 )
        {
            std::cerr << "EVP_MAC_update 初始化MAC上下文失败" << std::endl;
            EVP_MAC_CTX_free( ctx );
            EVP_MAC_free( mac );
            return false;
        }

        /*
            计算生成的HMAC的大小：
            函数原型
            int EVP_MAC_final(EVP_MAC_CTX *ctx,unsigned char *out, size_t *outl, size_t outsize);
            EVP_MAC_final（） 进行最终计算并将结果存储在 out of size outsize 指向的内存中，并设置以 *outl at
           写入的字节数。如果 out 为 NULL 或 outsize 太小，则不进行计算。要确定输出长度并动态为其分配空间，只需调用 out
           为 NULL 且 outl 指向有效位置，然后分配空间并进行第二次调用，而 out 指向分配的空间。
        */

        if ( EVP_MAC_final( ctx, NULL, outlen, 0 ) != 1 )
        {
            std::cerr << "EVP_MAC_final 获取HAMC大小失败";
            EVP_MAC_CTX_free( ctx );
            EVP_MAC_free( mac );
            return false;
        }

        unsigned char *hmac = ( unsigned char * )OPENSSL_malloc( *outlen );
        if ( !hmac )
        {
            std::cerr << "OPENSSL_malloc 为HMAC分配内存空间失败";
            EVP_MAC_CTX_free( ctx );
            EVP_MAC_free( mac );
            return false;
        }

        if ( EVP_MAC_final( ctx, hmac, outlen, *outlen ) != 1 )
        {
            std::cerr << "EVP_MAC_final 生成HMAC失败";
            EVP_MAC_CTX_free( ctx );
            EVP_MAC_free( mac );
            OPENSSL_free( hmac );
            return false;
        }
        *hmac_value = hmac;
        // std::cout << "计算MAC成功！" << std::endl;
        EVP_MAC_CTX_free( ctx );
        EVP_MAC_free( mac );
        return true;
    }

    bool verifyHmac( unsigned char *computeHmac, unsigned char *receiveHmac, size_t hmacLen )
    {
        return CRYPTO_memcmp( computeHmac, receiveHmac, hmacLen ) == 0;
    }
    void extractDroneData( std::vector< DroneData > &drones, std::string &data )
    {
        std::stringstream ss( data );
        std::string tmp;
        int i = 0;
        int creatDroneDataCount = 0;
        while ( std::getline( ss, tmp, ']' ) )
        {
            // 然后按逗号为分隔符来提取数据
            std::stringstream ss2( tmp );
            std::string tmp2;
            int j = 0;
            int k = 0;
            int l = 0;
            while ( std::getline( ss2, tmp2, ',' ) )
            {
                if ( tmp2.size() == 0 )
                {
                    continue;
                }
                // 要排除掉,为开头的情况,即只有一个
                // 找到第一个"之后的位置
                size_t start = tmp2.find( '\"' ) + 1;
                size_t end = tmp2.find( '\"', start );
                if ( start < end )
                {
                    if ( i == 0 )
                    {
                        // 第0次就是获取的ID,因此需要创建DroneData结构
                        DroneData d;
                        d.id = tmp2.substr( start, end - start );
                        drones.push_back( d );
                        creatDroneDataCount++;
                    }
                    else if ( i == 1 && j < creatDroneDataCount )
                    {
                        drones.at( j ).deviceType = tmp2.substr( start, end - start );
                        j++;
                    }
                    else if ( i == 2 && k < creatDroneDataCount )
                    {
                        drones.at( k ).model = tmp2.substr( start, end - start );
                        k++;
                    }
                    else if ( i == 3 && l < creatDroneDataCount )
                    {
                        drones.at( l ).status = tmp2.substr( start, end - start );
                        l++;
                    }
                }
            }
            ++i;
        }
    }

    std::vector< DroneData > parseReceiveDroneData( std::string data )
    {
        // std::cout << data << std::endl;
        std::vector< DroneData > drones;
        std::vector< DroneData > drones1;
        size_t firstLineStart = 0;
        ssize_t secondLineStart = 0;
        std::string firstLineDroneInfo;
        std::string secondLineDroneInfo;
        //[["0x12345678"],["DJI"],["master"],["legitimate"]]
        //[["0x12345687","0x123456789"],["DJI","DJI"],["master","master"],["illegal","illegal"]]

        // 首先查看有几行数据,查看分析的话，就是根据区块链返回的数据就是无论如何都会有一个换行
        size_t pos = data.find( '\n', firstLineStart );
        if ( pos == std::string::npos )
        {
            std::cerr << "返回的数据不正确" << std::endl;
            return drones;
        }
        // 找到了第一个换行符，查看后续还有没有换行符，这是为了查找是否有多行数据

        // 从\n的后面找是否还有数据
        size_t pos2 = data.find( '\n', pos + 1 );
        if ( pos2 != std::string::npos )
        {
            // 说明后续没有数据了
            secondLineStart = pos + 1;
            secondLineDroneInfo = data.substr( secondLineStart, pos2 );
        }
        // 获取第一行的数据,第一行是合法的无人机信息
        firstLineDroneInfo = data.substr( firstLineStart, pos );

        if ( !firstLineDroneInfo.empty() )
        {
            extractDroneData( drones, firstLineDroneInfo );
            // 提取子串
        }

        if ( !secondLineDroneInfo.empty() )
        {
            extractDroneData( drones1, secondLineDroneInfo );
        }
        drones.insert( drones.end(), drones1.begin(), drones1.end() );

        return drones;
    }

    // 这个函数一次只能读取一次，读取到一次就会返回
    ssize_t myMqTimeRead( mqd_t mq, char *data, size_t dataLen, int maxTries )
    {
        struct timespec tmsp;
        int tries = 0;
        while ( tries < maxTries )
        {

            // 获取系统超时时间，用来设计超时
            if ( clock_gettime( CLOCK_REALTIME, &tmsp ) == -1 )
            {
                perror( "clock_gettime" );
                exit( EXIT_FAILURE );
            }

            // 加上超时时间5S
            tmsp.tv_sec += 2;
            ssize_t n = mq_timedreceive( mq, ( char * )data, dataLen, NULL, &tmsp );
            // std::cout << tries << std::endl;
            if ( n > 0 )
            {
                return n;
            }
            else if ( errno == ETIMEDOUT || errno == EINTR || errno == EAGAIN )
            {
                ++tries;
                continue;  // 尝试再次读取
            }
            else
            {
                perror( "mq_timedreceive failed" );
                return -1;  // 其他错误
            }
        }
        // std::cout << tries << std::endl;
        return -2;
    }

    ssize_t myMqTimeSend( mqd_t mq, char *data, size_t dataLen, int maxTries )
    {
        struct timespec tmsp;
        int tries = 0;
        while ( tries < maxTries )
        {
            // 获取系统超时时间，用来设计超时
            if ( clock_gettime( CLOCK_REALTIME, &tmsp ) == -1 )
            {
                perror( "clock_gettime" );
                exit( EXIT_FAILURE );
            }

            // 加上超时时间5S
            tmsp.tv_sec += 0.5;
            ssize_t n = mq_timedsend( mq, data, dataLen, 0, &tmsp );
            if ( n < 0 )
            {
                if ( errno == EINTR || errno == ETIMEDOUT || errno == EAGAIN )
                {
                    ++tries;
                    continue;
                }
                else if ( errno == EINVAL )
                {
                    std::cerr << "The message queue descriptor is invalid, or the specified timeout is invalid"
                              << std::endl;
                    return -1;
                }
                {
                    perror( "The message length exceeds the maximum length allowed by the queue" );
                    return -1;
                }
            }
            else
            {
                return n;
            }
        }
        return -2;
    }

    void partially_Extract_WhiteOrBlack_DroneData( std::vector< DroneData > &drones, const std::string data, int i )
    {
        std::stringstream ss( data );
        std::string tmpstring;
        int index = 0;
        while ( std::getline( ss, tmpstring, ',' ) )
        {
            if ( !tmpstring.empty() && tmpstring.size() > 2 )
            {
                std::string partData( tmpstring.begin() + 1, tmpstring.end() - 1 );
                if ( i == 0 )
                {
                    drones[ index ].id = partData;
                    ++index;
                }
                else if ( i == 1 )
                {
                    drones[ index ].deviceType = partData;
                    ++index;
                }
                else if ( i == 2 )
                {
                    drones[ index ].model = partData;
                    ++index;
                }
                else if ( i == 3 )
                {
                    drones[ index ].status = partData;
                    ++index;
                }
                else
                {
                    std::cerr << "i的范围出错，i的范围为[0-3]!";
                    break;
                }
            }
        }
    }

    std::vector< DroneData > completeExtract( std::string data )
    {
        // std::cout << data << std::endl;
        std::string tmpdata( data.begin() + 1, data.end() - 1 );
        size_t possLeft[ 4 ];
        size_t possRigth[ 4 ];
        memset( possLeft, 0, sizeof( possLeft ) );
        memset( possRigth, 0, sizeof( possRigth ) );
        int i = 0;
        size_t posRight = 0;
        size_t posLeft = 0;
        do
        {
            posLeft = tmpdata.find( '[', posRight );
            posRight = tmpdata.find( ']', posLeft );
            if ( posLeft != std::string::npos && posRight != std::string::npos && posLeft < posRight )
            {
                possLeft[ i ] = posLeft;
                possRigth[ i ] = posRight;
                ++i;
            }

        } while ( posLeft != std::string::npos && posRight != std::string::npos && posLeft < posRight );

        std::string IDs( tmpdata.begin() + possLeft[ 0 ] + 1, tmpdata.begin() + possRigth[ 0 ] );
        std::string deviceType( tmpdata.begin() + possLeft[ 1 ] + 1, tmpdata.begin() + possRigth[ 1 ] );
        std::string model( tmpdata.begin() + possLeft[ 2 ] + 1, tmpdata.begin() + possRigth[ 2 ] );
        std::string status( tmpdata.begin() + possLeft[ 3 ] + 1, tmpdata.begin() + possRigth[ 3 ] );

        std::stringstream ss1( IDs );
        std::vector< DroneData > drones;
        std::string idTmp;

        while ( std::getline( ss1, idTmp, ',' ) )
        {
            // std::cout << idTmp << std::endl;
            std::string idTmpString( idTmp.begin() + 1, idTmp.end() - 1 );
            DroneData drone;
            drone.id = idTmpString;
            drones.emplace_back( drone );
        }

        partially_Extract_WhiteOrBlack_DroneData( drones, deviceType, 1 );
        partially_Extract_WhiteOrBlack_DroneData( drones, model, 2 );
        partially_Extract_WhiteOrBlack_DroneData( drones, status, 3 );
        return drones;
    }

    void divideBothDroneData( std::string rawData, std::string *illegalString, std::string *legitimateString )
    {
        // 检查\n所在的位置
        size_t pos = rawData.find( '\n' );
        if ( pos == std::string::npos )
        {
            if ( illegalString != NULL )
            {
                illegalString->assign( rawData );
            }
            else if ( legitimateString != NULL )
            {
                legitimateString->assign( rawData );
            }
            else
            {
                std::cerr << "Error: illegalString and legitimateString ptr is NULL " << std::endl;
            }
        }
        else
        {
            std::string tmp1( rawData.begin(), rawData.begin() + pos );
            std::string tmp2( rawData.begin() + pos + 1, rawData.end() );
            size_t pos = tmp1.find( "illegal" );
            if ( pos == std::string::npos )
            {
                // 没有找到illegal就说明，该数据是legitimate的数据
                legitimateString->assign( tmp1 );
                illegalString->assign( tmp2 );
            }
            else
            {
                illegalString->assign( tmp1 );
                legitimateString->assign( tmp2 );
            }
        }
    }
    bool createDirectory( const std::string &path )
    {
        struct stat info;

        if ( stat( path.c_str(), &info ) != 0 )
        {
            // 目录不存在，尝试创建
            if ( mkdir( path.c_str(), 0777 ) == -1 )
            {
                std::cerr << "Error creating directory: " << strerror( errno ) << std::endl;
                return false;
            }
        }
        else if ( info.st_mode & S_IFDIR )
        {
            // 目录已经存在
            return true;
        }
        else
        {
            std::cerr << "Path exists but is not a directory: " << path << std::endl;
            return false;
        }
        return true;
    }

    // 递归创建多级目录
    bool createDirectories( const std::string &path )
    {
        size_t pos = 0;
        std::string delimiter = "/";
        std::string currentPath;

        while ( ( pos = path.find( delimiter, pos ) ) != std::string::npos )
        {
            currentPath = path.substr( 0, pos );
            if ( !currentPath.empty() && !createDirectory( currentPath ) )
            {
                return false;
            }
            pos++;
        }

        // 创建最后一级目录
        return createDirectory( path );
    }

    ssize_t receiveUdp( int fd, std::string &inBuffer, struct sockaddr_in *sender_address, socklen_t *arrLen )
    {
        ssize_t nread = 0;
        ssize_t readSum = 0;

        unsigned char buff[ MAX_BUFF ];
        while ( true )
        {
            if ( ( nread = recvfrom( fd, buff, MAX_BUFF, 0, ( struct sockaddr * )sender_address, arrLen ) ) < 0 )
            {

                if ( errno == EINTR )
                {
                    continue;
                }
                else if ( errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    return readSum;
                }
                else
                {
                    perror( "recvfrom erro" );
                    return -1;
                }
            }
            break;
        }

        buff[ nread ] = '\0';
        std::string sender_ip = inet_ntoa( sender_address->sin_addr );
        std::string local_ip = getLocalIPAddress();
        if ( sender_ip != local_ip )
        {
            readSum += nread;
            inBuffer += std::string( buff, buff + nread );
        }
        return readSum;
    }

    ssize_t receiveUdpMore( int fd,
                            std::queue< std::string > &inBufferQueue,
                            struct sockaddr_in *sender_address,
                            socklen_t &arrLen,
                            std::mutex &mutex,
                            enum udpMessage *um )
    {
        char buffer[ BUFFER_SIZE ];
        struct iovec iov[ 1 ];
        struct msghdr msgh;
        ssize_t receiveNum = 0;
        // 为辅助数据分配一个缓冲区并设置内存对齐
        char control[ CMSG_SPACE( sizeof( struct in_pktinfo ) ) + 1024 ];
        // std::cout << "1876" << std::endl;
        while ( true )
        {
            // 这是设置msg和iovec结构体
            iov[ 0 ].iov_base = buffer;
            iov[ 0 ].iov_len = BUFFER_SIZE;
            msgh.msg_name = sender_address;
            msgh.msg_namelen = arrLen;
            msgh.msg_control = control;
            msgh.msg_controllen = sizeof( control );
            msgh.msg_iov = iov;
            msgh.msg_iovlen = 1;
            // msgh.msg_flags = 0;

            if ( ( receiveNum = recvmsg( fd, &msgh, MSG_DONTWAIT ) ) < 0 )
            {
                if ( errno == EINTR )
                {
                    continue;
                }
                else if ( errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    return receiveNum;
                }
                else
                {
                    perror( "recvmsg error" );
                    return -1;
                }
            }
            break;
        }
        buffer[ receiveNum ] = '\0';

        // std::string senderIp = inet_ntoa( sender_address->sin_addr );
        // std::string localIp = getLocalIPAddress();
        // std::cout << senderIp << std::endl;
        // std::cout << localIp << std::endl;
        struct in_pktinfo *ipv4Info = nullptr;
        struct cmsghdr *cmsg = CMSG_FIRSTHDR( &msgh );

        for ( ; cmsg != nullptr; cmsg = CMSG_NXTHDR( &msgh, cmsg ) )
        {
            if ( cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO )
            {
                ipv4Info = ( struct in_pktinfo * )CMSG_DATA( cmsg );
                break;
            }
        }

        if ( ipv4Info )
        {
            char target_ip[ INET_ADDRSTRLEN ];
            inet_ntop( AF_INET, &( ipv4Info->ipi_addr ), target_ip, INET_ADDRSTRLEN );
            // std::cout << target_ip << std::endl;
            if ( strcmp( target_ip, BROADCAST_IP ) == 0 )
            {
                *um = BROADCAST_MESSAGE;
            }
            else if ( strcmp( target_ip, MULTICAST_IP ) == 0 )
            {
                *um = MULTICAST_MESSAGE;
            }
            else
            {
                *um = UNICAST_MESSAGE;
            }
        }

        std::string tmpString( buffer, receiveNum );
        {
            std::lock_guard< std::mutex > lock( mutex );
            inBufferQueue.emplace( tmpString );
        }
        return receiveNum;
    }
    ssize_t receiveUdpData( int fd, struct commMessage *messageInfo )
    {
        char buffer[ BUFFER_SIZE ];
        struct iovec iov[ 1 ];
        struct msghdr msgh;
        ssize_t receiveNum = 0;
        // 为辅助数据分配一个缓冲区并设置内存对齐
        char control[ CMSG_SPACE( sizeof( struct in_pktinfo ) ) + 1024 ];
        // std::cout << "1876" << std::endl;
        while ( true )
        {
            // 这是设置msg和iovec结构体
            iov[ 0 ].iov_base = buffer;
            iov[ 0 ].iov_len = BUFFER_SIZE;
            msgh.msg_name = &( messageInfo->sendAddress );
            msgh.msg_namelen = messageInfo->address_len;
            msgh.msg_control = control;
            msgh.msg_controllen = sizeof( control );
            msgh.msg_iov = iov;
            msgh.msg_iovlen = 1;
            // msgh.msg_flags = 0;

            if ( ( receiveNum = recvmsg( fd, &msgh, 0 ) ) < 0 )
            {
                if ( errno == EINTR )
                {
                    continue;
                }
                else if ( errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    return receiveNum;
                }
                else
                {
                    perror( "recvmsg error" );
                    return -1;
                }
            }
            break;
        }
        buffer[ receiveNum ] = '\0';

        // std::string senderIp = inet_ntoa( sender_address->sin_addr );
        // std::string localIp = getLocalIPAddress();
        // std::cout << senderIp << std::endl;
        // std::cout << localIp << std::endl;
        struct in_pktinfo *ipv4Info = nullptr;
        struct cmsghdr *cmsg = CMSG_FIRSTHDR( &msgh );  // 这个代码的作用是获取辅助数据的第一个控制消息头

        for ( ; cmsg != nullptr; cmsg = CMSG_NXTHDR( &msgh, cmsg ) )
        {
            if ( cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO )
            {
                ipv4Info = ( struct in_pktinfo * )CMSG_DATA( cmsg );
                break;
            }
        }

        if ( ipv4Info )
        {
            char target_ip[ INET_ADDRSTRLEN ];
            inet_ntop( AF_INET, &( ipv4Info->ipi_addr ), target_ip, INET_ADDRSTRLEN );
            // std::cout << target_ip << std::endl;
            if ( strcmp( target_ip, BROADCAST_IP ) == 0 )
            {
                messageInfo->um = BROADCAST_MESSAGE;
            }
            else if ( strcmp( target_ip, MULTICAST_IP ) == 0 )
            {
                messageInfo->um = MULTICAST_MESSAGE;
            }
            else
            {
                messageInfo->um = UNICAST_MESSAGE;
            }
        }

        std::string tmpString( buffer, receiveNum );
        messageInfo->data.assign( tmpString );
        return receiveNum;
    }
    ssize_t sendtoUdp( int fd, std::string &outBuffer, struct sockaddr_in *dest_address, socklen_t dest_arrLen )
    {
        int retriesNum = 10;
        ssize_t sendNum = 0;
        int sendCount = 0;
        size_t sendLen = outBuffer.size();

        while ( sendCount < retriesNum )
        {

            if ( ( sendNum =
                       sendto( fd, outBuffer.c_str(), sendLen, 0, ( struct sockaddr * )dest_address, dest_arrLen ) )
                 < 0 )
            {
                if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    sendCount++;
                    continue;
                }
                else
                {
                    perror( "sendto erro" );
                    return -1;
                }
            }
            break;
        }
        if ( sendNum > 0 )
        {
            outBuffer.clear();
        }
        else
        {
            std::cerr << "Failed to send data after " << retriesNum << " attempts." << std::endl;
        }
        return sendNum;
    }
    ssize_t sendUdpMore( int fd,
                         std::string &content,
                         struct sockaddr_in destination_address,
                         socklen_t &arrLen,
                         std::string destination_address_str )
    {
        char buff[ 4096 ];
        size_t contentLen = content.size();
        memcpy( buff, content.c_str(), contentLen );

        struct msghdr msg;
        char cmsgbuf[ CMSG_SPACE( sizeof( struct in_pktinfo ) ) ];
        struct cmsghdr *cmsg;
        struct in_pktinfo *pktinfo;

        memset( &msg, 0, sizeof( msg ) );
        memset( cmsgbuf, 0, CMSG_SPACE( sizeof( struct in_pktinfo ) ) );
        struct iovec iov[ 1 ];
        iov->iov_base = buff;
        iov->iov_len = contentLen;

        msg.msg_name = &destination_address;
        msg.msg_namelen = sizeof( destination_address );
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
        // msg.msg_flags = 0;
        msg.msg_control = cmsgbuf;
        msg.msg_controllen = sizeof( cmsgbuf );

        // 从msg中获取第一个cmsg
        cmsg = CMSG_FIRSTHDR( &msg );
        cmsg->cmsg_level = IPPROTO_IP;
        cmsg->cmsg_type = IP_PKTINFO;
        cmsg->cmsg_len = CMSG_LEN( sizeof( struct in_pktinfo ) );

        // 然后将辅助信息填入到cmsg中
        // 获取指针,就能够直接休息内存中的数据
        // 一般内存中的数据都是使用char类型存放因为，数据大多是二进制的
        pktinfo = ( struct in_pktinfo * )CMSG_DATA( cmsg );
        inet_pton( AF_INET, destination_address_str.c_str(), &pktinfo->ipi_addr );

        int retriesNum = 10;
        ssize_t sendNum = 0;
        int sendCount = 0;
        while ( sendCount < retriesNum )
        {
            if ( ( sendNum = sendmsg( fd, &msg, MSG_DONTWAIT ) ) < 0 )
            {
                if ( errno == EINTR )
                {
                    ++sendCount;
                    continue;
                }
                else if ( errno == EAGAIN || errno == EWOULDBLOCK )
                {
                    return sendNum;
                }
                else
                {
                    perror( "sendMsg error!" );
                    return -1;
                }
            }
            break;
        }
        // std::cout << "数据发送成功，发送的数据大小为：" << sendNum << std::endl;
        return sendNum;
    }

    BIGNUM *generate_large_serial_number()
    {
        BIGNUM *bn = BN_new();
        if ( !bn )
        {
            std::cerr << "Failed to create BIGNUM." << std::endl;
            return nullptr;
        }

        if ( !BN_rand( bn, 128, 0, 0 ) )
        {
            std::cerr << "Failed to generate random number." << std::endl;
            BN_free( bn );
            return nullptr;
        }
        return bn;
        // 生成一千万个序列号发生碰撞的概率为1.47*10^-25次方
    }
    /*
    获取本地除环回地址之外的所有IP地址：
    1、创建ifaddrs类型的结构体指针来指向ifaddrs结构体
    2、调用getifaddrs函数来获取本地系统上的网络接口信息，并将这些信息存储在一个链表(ifaddr)中。
    3、遍历链表，并判断是否为ipv4协议簇，并且标志flag不为IFF_LOOPBACK。
    4、如果满足条件，则调用getnameinfo函数从一个套接字地址结构获取主机名和服务器名。

        //函数原型：
        int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                char *host, size_t hostlen,
                char *serv, size_t servlen, int flags);

        const struct sockaddr *sa: 指向包含目标地址信息的套接字地址结构体的指针。
        socklen_t salen: 套接字地址结构体的大小（字节数）。
        char *host: 存储主机名或地址字符串的缓冲区。
        size_t hostlen: host 缓冲区的大小。
        char *serv: 存储服务名或端口号字符串的缓冲区（可以为 NULL）。
        size_t servlen: serv 缓冲区的大小。
        int flags: 标志参数，控制函数行为，如 NI_NUMERICHOST 强制返回数字形式的主机地址

    流程大致为：
    获取主机信息并存放到套接字ifaddrs中---->遍历ifaddrs-----> 从ifaddrs中获取主机名和服务器名
    */
    std::string getLocalIPAddress()
    {
        struct ifaddrs *ifaddr, *ifa;
        // ifaddr用来记录地址链表的起始位置,ifa用来移动指针来访问整个链表元素
        char host[ NI_MAXHOST ];
        std::string local_ip;

        // 获取本地所有的IP地址
        if ( getifaddrs( &ifaddr ) == -1 )
        {
            perror( "getifaddrs" );
            exit( EXIT_FAILURE );
        }

        for ( ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next )
        {
            if ( ifa->ifa_addr == nullptr )
            {
                continue;
            }
            // 检查是否为IP地址且不为环回地址
            if ( ifa->ifa_addr->sa_family == AF_INET && !( ifa->ifa_flags & IFF_LOOPBACK ) )
            {
                int s = getnameinfo(
                    ifa->ifa_addr, sizeof( struct sockaddr_in ), host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST );
                if ( s != 0 )
                {
                    std::cerr << "getnameinfo() failed: " << gai_strerror( s ) << std::endl;
                    continue;
                }
                local_ip = host;
            }
        }

        freeifaddrs( ifaddr );
        return local_ip;
    }

    bool readPubKeyCertificate( const std::string &path, std::string &cerStr )
    {

        // 首先打开文件
        std::ifstream ifs( path, std::ios_base::in );

        if ( !ifs.is_open() )
        {
            std::cerr << "Failed to open the " << path << "." << std::endl;
            return false;
        }

        std::string pemString( ( std::istreambuf_iterator< char >( ifs ) ), std::istreambuf_iterator< char >() );
        cerStr.append( pemString );
        ifs.close();
        return true;
    }

    bool generateHmacKey( unsigned char *AesKey, std::string token )
    {

        const char *token_c = token.c_str();
        const char *salt = "0x0203e8b6fc8cdf9636fddc1c4ea8c2e79b3fee94";

        // Generate key using PKCS5_PBKDF2_HMAC
        int iterations = 10000;
        int result = PKCS5_PBKDF2_HMAC( token_c,
                                        strlen( token_c ),
                                        reinterpret_cast< const unsigned char * >( salt ),
                                        strlen( salt ),
                                        iterations,
                                        EVP_sha256(),
                                        32,
                                        AesKey );
        if ( result != 1 )
        {
            std::cout << "Error in generating key" << std::endl;
            return false;
        }
        return true;
    }
    int compareASN1Time( const ASN1_TIME *time1, const ASN1_TIME *time2 )
    {
        int day = 0, sec = 0;
        if ( ASN1_TIME_diff( &day, &sec, time1, time2 ) == 0 )
        {
            std::cerr << "Error comparing ASN1_TIME." << std::endl;
            return -2;  // 返回 -1 表示比较失败
        }
        if ( day > 0 || ( day == 0 && sec > 0 ) )
        {
            // time1在time2前面
            return 1;
        }
        else if ( day < 0 || ( day == 0 && sec < 0 ) )
        {
            // time1 在tme2后面
            return -1;
        }
        else
        {
            return 0;
        }
    }
    bool check_certificate_content_validity_period( X509 *pubCert )
    {
        // 检查证书的结构
        if ( X509_get_subject_name( pubCert ) == NULL )
        {
            std::cerr << "Certificate does not have a subject name" << std::endl;
            return false;
        }

        if ( X509_get_issuer_name( pubCert ) == NULL )
        {
            return false;
        }

        if ( X509_get0_notBefore( pubCert ) == NULL || X509_get0_notAfter( pubCert ) == NULL )
        {
            std::cerr << "Certificate does not have valid notBefore or notAfter dates" << std::endl;
            return false;
        }

        if ( X509_get0_pubkey( pubCert ) == NULL )
        {
            std::cerr << "Certificate does not have a public key" << std::endl;
            return false;
        }

        // 尝试获取扩展字段
        int extCount = X509_get_ext_count( pubCert );
        for ( int i = 0; i < extCount; ++i )
        {
            X509_EXTENSION *ext = X509_get_ext( pubCert, i );
            if ( !ext )
            {
                std::cerr << "Failed to retrieve certificate extension" << std::endl;
                return false;
            }
        }

        // 验证证书的有效期
        const ASN1_TIME *notBefore = X509_get0_notBefore( pubCert );
        const ASN1_TIME *notAfter = X509_get0_notAfter( pubCert );
        if ( !notBefore || !notAfter )
        {
            std::cerr << "Invalid certificate validity period." << std::endl;
            return false;
        }
        // 需要验证是否到期
        //  1、时间转换
        //  time_t notBeforeTime = ASN1_TIME_to_time_t( notBefore );
        //  time_t notAfterTime = ASN1_TIME_to_time_t( notAfter );
        //  2、获取当前时间
        time_t currentTime = time( NULL );

        // 创建新的ASN1_TIME
        ASN1_TIME *asn1_current = ASN1_TIME_new();
        if ( !asn1_current )
        {
            perror( "asn1_current" );
            X509_free( pubCert );
            return false;
        }

        if ( !ASN1_TIME_set( asn1_current, currentTime ) )
        {
            perror( "ASN1_TIME_set" );
            ASN1_TIME_free( asn1_current );
            X509_free( pubCert );
            return false;
        }

        // 3、比较有效期
        int ret1 = compareASN1Time( asn1_current, notBefore );
        int ret2 = compareASN1Time( asn1_current, notAfter );

        ASN1_TIME_free( asn1_current );
        // 证书有效的情况是，ret1=1而 ret2 =-1
        if ( ( ret1 == -1 || ret1 == 0 ) && ret2 == 1 )
        {
            std::cerr << "Certificate is currently valid." << std::endl;
            return true;
        }
        else if ( ret1 == -2 || ret2 == -2 )
        {
            std::cerr << "Time comparison failed" << std::endl;
            return false;
        }
        else
        {
            std::cerr << "Certificate is currently invalid." << std::endl;
            return false;
        }
    }

    bool Extract_and_verify_cert_is_valid( X509 **pubCert, const std::string &certificatePath )
    {
        struct stat statBuf;

        if ( stat( certificatePath.c_str(), &statBuf ) < 0 )
        {
            std::cerr << certificatePath << "file not found" << std::endl;
            return false;
        }
        // 判断文件中是否有内容
        if ( statBuf.st_size == 0 )
        {
            // 说明文件里面是空的
            std::cerr << "The content of file " << certificatePath << " is empty" << std::endl;
            return false;
        }

        // 有内容
        FILE *file = fopen( certificatePath.c_str(), "rb" );
        if ( !file )
        {
            std::cerr << certificatePath << "File open failed" << std::endl;
            return false;
        }

        X509 *cert = PEM_read_X509( file, NULL, NULL, NULL );
        fclose( file );

        if ( !cert )
        {
            std::cerr << "Error reading certificate" << std::endl;
            return false;
        }
        // 检查证书的结构和有效期
        bool is_valid = check_certificate_content_validity_period( cert );
        if ( !is_valid )
        {
            std::cerr << "证书的内容无效或有效期已到" << std::endl;
            X509_free( cert );
        }
        *pubCert = cert;
        return true;
    }

    void print_openssl_error()
    {
        unsigned long err;
        while ( ( err = ERR_get_error() ) )
        {
            char *err_str = ERR_error_string( err, NULL );
            std::cerr << "OpenSSL Error: " << err_str << std::endl;
        }
    }

    int getRandomPort()
    {
        // 创建随机设备和随机数生成器
        std::random_device rd;
        std::mt19937 gen( rd() );

        // 定义随机数分布范围为10001到10004
        std::uniform_int_distribution<> distrib( 10001, 10004 );

        // 生成并返回随机端口号
        return distrib( gen );
    }

    char *encode_csr_to_pem( X509_REQ *req )
    {
        // 首先创建一个新的BIO内存缓冲区
        BIO *bio = BIO_new( BIO_s_mem() );
        // 然后就是将X509_REQ对象编码成PEM格式并写入到内存缓冲区中
        int i = PEM_write_bio_X509_REQ( bio, req );
        if ( i != 1 )
        {
            std::cerr << "PEM_write_bio_X509_REQ is error" << std::endl;
            return NULL;
        }

        // 从内存BIO中获取数据
        char *pem_data;
        long pem_size = BIO_get_mem_data( bio, &pem_data );
        // pem_data将执行BIO内存中的数据
        char *pem_c = ( char * )malloc( pem_size + 1 );  //+1是需要末尾填充\0
        memcpy( pem_c, pem_data, pem_size );
        pem_c[ pem_size ] = '\0';

        BIO_free( bio );
        return pem_c;
    }

    X509_REQ *decode_csr_from_pem( const char *pem_c )
    {
        BIO *bio = BIO_new_mem_buf( pem_c, -1 );

        X509_REQ *req = PEM_read_bio_X509_REQ( bio, NULL, NULL, NULL );
        if ( !req )
        {
            std::cerr << "PEM_read_bio_X509_REQ is error!" << std::endl;
            return NULL;
        }

        BIO_free( bio );
        return req;
    }

    char *encode_Cert_to_pem( X509 *cert )
    {
        BIO *bio = BIO_new( BIO_s_mem() );

        int i = PEM_write_bio_X509( bio, cert );

        if ( i != 1 )
        {
            std::cerr << "PEM_write_bio_X509 is error" << std::endl;
            return NULL;
        }

        // 获取BIO内存中的数据
        //  1、设置指针指向BIO内存中的数据，使用BIO_get_mem_data，将返回内存数据的大小
        //  2、根据数据大小，创建一个接收的缓冲区，将数据复制到缓冲区中。
        char *pem_data;
        long pem_size = BIO_get_mem_data( bio, &pem_data );
        char *pem_c = ( char * )malloc( pem_size + 1 );
        memcpy( pem_c, pem_data, pem_size );
        pem_c[ pem_size ] = '\0';
        BIO_free( bio );
        return pem_c;
    }

    X509 *decode_Cert_from_pem( const char *pem_c )
    {
        BIO *bio = BIO_new_mem_buf( pem_c, -1 );
        if ( !bio )
        {
            std::cerr << "Failed to create BIO" << std::endl;
            return NULL;
        }
        X509 *cert = PEM_read_bio_X509( bio, NULL, NULL, NULL );
        if ( !cert )
        {
            std::cerr << "Failed to read X509 cert from BIO" << std::endl;
        }
        BIO_free( bio );
        return cert;
    }

    // 这个函数是用于将公钥字符串转换为EVP_PKEY类型
    EVP_PKEY *stringToEVP_PKEY( const std::string &pubKeyStr )
    {
        if ( pubKeyStr.empty() )
        {
            std::cerr << "pubKeyStr is empty" << std::endl;
            return NULL;
        }

        BIO *bio = BIO_new_mem_buf( pubKeyStr.c_str(), -1 );
        if ( !bio )
        {
            std::cerr << "Failed to create BIO" << std::endl;
            return NULL;
        }

        EVP_PKEY *pubKey = PEM_read_bio_PUBKEY( bio, NULL, NULL, NULL );
        if ( !pubKey )
        {
            std::cerr << "Failed to read public key from BIO" << std::endl;
        }
        BIO_free( bio );
        return pubKey;
    }
    // 这个是将公钥转换为字符串pem形式
    std::string EVP_PKEYToString( EVP_PKEY *pkey )
    {
        BIO *bio = BIO_new( BIO_s_mem() );
        if ( !bio )
        {
            std::cerr << "Failed to create BIO" << std::endl;
            return "";
        }

        if ( !PEM_write_bio_PUBKEY( bio, pkey ) )
        {  // 将EVP_PKEY写入BIO
            std::cerr << "Failed to write public key to BIO" << std::endl;
            BIO_free( bio );
            return "";
        }

        char *pem_data;
        long pem_size = BIO_get_mem_data( bio, &pem_data );
        std::string pem_str( pem_data, pem_size );
        return pem_str;
    }

    bool checkTimestamp_Num( const std::string &timeStamp, const std::string checkNum, const std::string &data )
    {
        // 获取时间戳
        //  std::cout << timeStamp << std::endl;
        uint64_t nowTime = getTime();
        uint64_t time = std::stoll( timeStamp );
        // std::cout << nowTime << std::endl;
        // 还需要检查checkNum
        size_t data_len = data.size();
        unsigned char data_c[ data_len ];
        memcpy( data_c, data.c_str(), data_len );
        // 计算检验和
        std::string checkNum1 = sha256_check( data_c, data_len );
        int compareRet = checkNum.compare( checkNum1 );
        int timeCompareRet = nowTime - 3000000 - time;
        // std::cout << timeCompareRet << std::endl;
        if ( timeCompareRet <= 0 && compareRet == 0 )
        {
            return true;
        }
        else
        {
            // std::cout << timeCompareRet << std::endl;
            return false;
        }
    }
    std::string getIpString( struct sockaddr_in sendAddress )
    {
        char src_ip[ INET_ADDRSTRLEN ];
        if ( inet_ntop( AF_INET, &( sendAddress.sin_addr ), src_ip, INET_ADDRSTRLEN ) == NULL )
        {
            perror( "inet_ntop failed" );
            return "";
        }
        else
        {
            std::string senderIp( src_ip );  // 直接使用 src_ip 创建字符串，自动确定长度
            return senderIp;
        }
    }
}  // namespace droneswarm